home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * HSN Datatype, based on the sourcecode found in OS3.1 Native Developer Kit
- *
- * Written by Christian Buchner
- *
- ******************************************************************************
- * dispatch.c
- */
-
- #include "classbase.h"
-
- /*****************************************************************************/
-
- #define DEBUG 1
-
- #if DEBUG
-
- #define DB(x) x
-
- #include <stdarg.h>
- void __stdargs Error(struct ClassBase *cb,UBYTE *Msg,...)
- {
- va_list Arg;
- struct EasyStruct Req={sizeof(struct EasyStruct),0,"HSN debug message",0,"Okay"};
- va_start(Arg,Msg);
- Req.es_TextFormat=Msg;
- EasyRequestArgs(NULL,&Req,0,Arg);
- va_end(Arg);
- }
-
- #else
-
- #define DB(x)
-
- #endif
-
-
-
- /*****************************************************************************/
-
- Class *initClass (struct ClassBase * cb)
- {
- Class *cl;
-
- if (cl = MakeClass (HSNDTCLASS, SOUNDDTCLASS, NULL, NULL, 0L))
- {
- cl->cl_Dispatcher.h_Entry = (ULONG (*)())Dispatch;
- cl->cl_UserData = (ULONG) cb;
- AddClass (cl);
- }
-
- return (cl);
- }
-
- /*****************************************************************************/
-
- ULONG ASM Dispatch (REG (a0) Class * cl, REG (a2) Object * o, REG (a1) Msg msg)
- {
- struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
- ULONG retval = 0L;
-
- switch (msg->MethodID)
- {
- case OM_NEW:
- if (retval = DoSuperMethodA (cl, o, msg))
- {
- if (!(ConvertObjectData (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList)))
- {
- CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
- retval = NULL;
- }
- }
- break;
-
- /* Let the superclass handle everything else */
-
- default:
- retval = (ULONG) DoSuperMethodA (cl, o, msg);
- break;
- }
-
- return (retval);
- }
-
- /*****************************************************************************/
-
- struct HSNHeader
- {
- UBYTE HSN_ID[8]; /* $00 */
- UBYTE Unknown[12]; /* $08 */
- ULONG Size; /* $14 */
- UWORD Pitch; /* $18 */
- UBYTE Unknown2[22]; /* $1a */
- /* $30 */
- };
-
- /*****************************************************************************/
-
- BOOL ConvertObjectData (struct ClassBase * cb, Class * cl, Object * o, struct TagItem * attrs)
- {
- LONG ErrorCode=0;
- struct FileInfoBlock *fib;
- struct VoiceHeader *vhdr;
- STRPTR Title;
- BPTR FH;
- struct HSNHeader *HSNHeader;
- UBYTE HSNDesc[42]="";
- ULONG Memory;
- UBYTE *Sample;
- ULONG Size;
-
- Title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
-
- getdtattrs (cb, o,
- SDTA_VoiceHeader, &vhdr,
- DTA_Handle, &FH,
- TAG_DONE);
-
- if (FH && vhdr)
- {
- /* Allocate a temporary file info block */
- if (!(fib = (struct FileInfoBlock *) AllocMem (sizeof (struct FileInfoBlock), NULL)))
- {
- ErrorCode=ERROR_NO_FREE_STORE;
- }
- else
- {
- /* Get the size of the file */
- if (ExamineFH (FH, fib))
- {
- Size = fib->fib_Size;
- }
- else
- {
- Seek (FH, 0, OFFSET_END);
- Size = Seek (FH, 0, OFFSET_BEGINNING);
- }
-
- /* Free the temporary file info block */
- FreeMem (fib, sizeof (struct FileInfoBlock));
-
- /* Allocate header structure */
- if (!(HSNHeader=AllocVec(sizeof(struct HSNHeader),MEMF_ANY)))
- {
- ErrorCode=ERROR_NO_FREE_STORE;
- }
- else
- {
- /* Calculate size from actual file length */
- /* So even crippled or overlong files can be played completely */
- Size-=sizeof(struct HSNHeader);
-
- /* Read in sample header */
- if (Read(FH,HSNHeader,sizeof(struct HSNHeader))==sizeof(struct HSNHeader))
- {
- /* Versions 1.0 and 1.1 are supported */
- if (strcmp("HSND1.1",HSNHeader->HSN_ID) && strcmp("HSND1.0",HSNHeader->HSN_ID))
- {
- ErrorCode=ERROR_OBJECT_WRONG_TYPE;
- }
- else
- {
- /* Version 1.1 features a short description */
- if (HSNHeader->HSN_ID[6]=='1')
- {
- Size-=sizeof(HSNDesc);
-
- Read(FH,HSNDesc,sizeof(HSNDesc));
- }
-
- /* sound.datatype V40 can replay */
- /* directly from Fast RAM */
-
- Memory = (SuperClassBase->lib_Version>39) ?
- MEMF_ANY : MEMF_CHIP;
-
- /* Allocate a buffer with the calculated size */
- if (!(Sample=AllocVec(Size,Memory)))
- {
- ErrorCode=ERROR_NO_FREE_STORE;
- }
- else
- {
- /* This implies that sample data is 8 bit signed */
- /* Just read the sample into the buffer */
- if (Read(FH,Sample,Size)==Size)
- {
- /* Fill in the VoiceHeader */
- memset(vhdr,0,sizeof(struct VoiceHeader));
- vhdr->vh_OneShotHiSamples = Size;
- vhdr->vh_SamplesPerSec = 10*HSNHeader->Pitch;
- vhdr->vh_Octaves = 1;
- vhdr->vh_Compression = CMP_NONE;
- vhdr->vh_Volume = 64;
-
- /* Tell the super-class about the attributes */
- setdtattrs (cb, o,
- DTA_ObjName, Title,
- SDTA_Sample, Sample,
- SDTA_SampleLength, Size,
- SDTA_Period, (ULONG)(SysBase->ex_EClockFrequency*5)/(ULONG)vhdr->vh_SamplesPerSec,
- SDTA_Volume, 64,
- SDTA_Cycles, 1,
- TAG_DONE);
- }
- }
- }
- }
- FreeVec(HSNHeader);
- }
- }
- }
- if (ErrorCode)
- {
- SetIoErr(ErrorCode);
- return(FALSE);
- }
- return(TRUE);
- }
-
-
- /*****************************************************************************/
-
- ULONG setdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
- {
- return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
- }
-
- /*****************************************************************************/
-
- ULONG getdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
- {
- return (GetDTAttrsA (o, (struct TagItem *) & data));
- }
-